package com.piece.mall.service;

import com.piece.core.framework.support.bootstrap.TreeData;
import com.piece.core.framework.support.convert.Convert;
import com.piece.core.jpa.repository.BaseService;
import com.piece.mall.model.WmsShArea;
import com.piece.mall.repository.WmsShAreaRepository;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

@Service
@Transactional
public class WmsShAreaService extends BaseService<WmsShArea, String> {

    @Autowired
    private WmsShAreaRepository wmsShAreaRepository;

    @PostConstruct
    public void initRepository() {
        setRepository(wmsShAreaRepository);
    }

    public WmsShArea findByZipCode(String zipCode) {
        List<WmsShArea> areaList = wmsShAreaRepository.findByCondition("zipCode", zipCode, null);
        return CollectionUtils.isNotEmpty(areaList) ? areaList.get(0) : null;
    }

    public List<WmsShArea> findByParent(Long pid) {
        HashMap<String, Object> condition = new HashMap<>();
        condition.put("pid", pid);
        return wmsShAreaRepository.findByCondition(condition, generateDefaultOrder());
    }

    /**
     * 查询省市区完整路径
     */
    public String[] findPathByZipCode(String zipCode) {
        List<String> path = new ArrayList<>();
        WmsShArea area = findByZipCode(zipCode);
        if (null != area) {
            List<String> fullPath = findParentPath(area.getId(), path);
            Collections.reverse(fullPath);
            return fullPath.toArray(new String[fullPath.size()]);
        } else {
            return new String [0];
        }
    }

    private List<String> findParentPath(Long id, List<String> path) {
        path.add(id + "");
        WmsShArea area = this.findById(id);
        if (0 != area.getPid()) {
            findParentPath(area.getPid(), path);
        }
        return path;
    }

    /**
     * 对象转分类树
     *
     * @param areaList 区域列表
     * @return
     */
    public List<TreeData> findTreeData(List<WmsShArea> areaList) {
        return findTreeData(areaList, null);
    }

    /**
     * 对象转分类树
     *
     * @param rootList     区域列表
     * @param selectedList 已存在区域列表
     * @return
     */
    public List<TreeData> findTreeData(List<WmsShArea> rootList, List<String> selectedList) {
        List<TreeData> trees = new ArrayList<>();
        boolean checked;
        for (WmsShArea area : rootList) {
            TreeData treeData = TreeData.builder()
                    .id(String.valueOf(area.getId()))
                    .pId(String.valueOf(area.getPid()))
                    .title(area.getZipCode())
                    .name(area.getName())
                    .build();

            if (CollectionUtils.isNotEmpty(selectedList)) {
                if (area.getId().equals(Convert.toLong(selectedList.get(0)))) {
                    // 设置子节点
                    setChildren(treeData, selectedList, 2);
                }
            }

            if (area.getLevel().equals(3L)) {
                treeData.setLeaf(true);
            } else {
                treeData.setLeaf(false);
            }

            treeData.setChecked(false);
            trees.add(treeData);
        }
        return trees;
    }

    private void setChildren(TreeData treeData, List<String> ids, int level) {
        if (level > 0) {
            WmsShArea child = findById(Convert.toLong(ids.get(ids.size() - level)));
            List<WmsShArea> children = findByParent(child.getPid());
            List<TreeData> childrenData = new ArrayList<>();
            for (WmsShArea child_ : children) {
                TreeData treeData_ = TreeData.builder()
                        .id(String.valueOf(child_.getId()))
                        .pId(String.valueOf(child_.getPid()))
                        .title(child_.getZipCode())
                        .name(child_.getName())
                        .build();
                if (child_.getId().equals(child.getId())) {
                    setChildren(treeData_, ids, --level);
                }
                if (child_.getLevel().equals(3L)) {
                    treeData_.setLeaf(true);
                } else {
                    treeData_.setLeaf(false);
                }
                childrenData.add(treeData_);
            }

            treeData.setChildren(childrenData);
            treeData.setLeaf(false);
        } else {
            treeData.setLeaf(true);
        }
    }
}
